using DG.Tweening;
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.OnScreen;
using UnityEngine.UI;

public class DynamicUIButton : OnScreenControl, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
    public bool needInputBinding = false;
    private Graphic buttonBg;
    [SerializeField] private Color normalColor = Color.white;
    [SerializeField] private Color pressedColor = new Color(0.7f, 0.7f, 0.7f, 1f);
    [SerializeField] private Color HighlightedColor = new Color(0.9f, 0.9f, 0.9f, 1f); 
    [Range(0, 1)] public float PointerDownScale = 0.9f;
    [SerializeField] public float clickDownScaleFadeDuration = 0.1f;
    [SerializeField] public float clickUpScaleFadeDuration = 0.12f;
    [SerializeField] public float colorFadeDuration = 0.1f;

    private RectTransform rectTransform;
    private Tweener clickDown;
    private Tweener clickUp;
    private Tweener colorTween;
    private bool isPointerInside = false;
    private bool isPressed = false;

    [InputControl(layout = "Button")]
    [SerializeField]
    private string m_ControlPath;

    public Action onClick;

    private void Awake()
    {
        buttonBg = GetComponent<Graphic>();
        rectTransform = GetComponent<RectTransform>();
        buttonBg.color = normalColor;
    }

    protected override string controlPathInternal
    {
        get => m_ControlPath;
        set => m_ControlPath = value;
    }

    public void OnPointerDown(PointerEventData data)
    {
        if (needInputBinding)
        {
            SendValueToControl(1.0f);
        }

        isPressed = true;
        clickDown?.Kill();
        clickDown = rectTransform.DOScale(Vector3.one * PointerDownScale, clickDownScaleFadeDuration);
        ChangeColor(pressedColor);
    }

    public void OnPointerUp(PointerEventData data)
    {
        if (needInputBinding)
        {
            SendValueToControl(0.0f);
        }

        isPressed = false;
        clickUp?.Kill();
        clickUp = rectTransform.DOScale(Vector3.one, clickUpScaleFadeDuration);
        Color targetColor = isPointerInside ? HighlightedColor : normalColor;
        ChangeColor(targetColor);
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        onClick?.Invoke();
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        isPointerInside = true;
        if (!isPressed)
        {
            ChangeColor(HighlightedColor);
        }
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        isPointerInside = false;
        if (!isPressed)
        {
            ChangeColor(normalColor);
        }
    }

    private void ChangeColor(Color targetColor)
    {
        if (buttonBg == null) return;

        colorTween?.Kill();
        colorTween = buttonBg.DOColor(targetColor, colorFadeDuration);
    }
}